package com.zhang.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zhang.common.util.result.R;
import com.zhang.system.vo.ModifyRoleVO;
import com.zhang.system.vo.UserPermissionVo;
import com.zhang.system.entity.Menu;
import com.zhang.system.entity.RoleMenu;
import com.zhang.system.mapper.RoleMenuMapper;
import com.zhang.system.service.IMenuService;
import com.zhang.system.service.IRoleMenuService;
import com.zhang.system.entity.Role;
import com.zhang.system.service.IRoleService;
import com.zhang.system.service.IUserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 关联表：角色与菜单权限表 服务实现类
 * </p>
 *
 * @author 创世神
 * @since 2023-07-06
 */
@Service
@Slf4j
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {

    @Autowired
    private IMenuService menuService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public List<Menu> getMenuFromRoleId(Long roleId) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        List<RoleMenu> list = list(wrapper);
        if (list.size() == 0 || list == null) {
            log.error("该角色没有权限!");
            return null;
        }
        List<Long> collect = list.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        boolean isAdmin = roleService.isAdmin(roleId);
        if (isAdmin) {
            return menuService.list();
        }
        return menuService.listByIds(collect);
    }

    @Override
    public List<RoleMenu> getRoleMenuFromRoles(List<Long> roleIds) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.in("role_id", roleIds);
        List<RoleMenu> list = list(wrapper);
        return list;
    }

    @Override
    public List<Menu> getMenuFromRole(List<Role> roles) {
        List<String> collect = roles.stream().map(Role::getRoleKey).collect(Collectors.toList());
        /*如果是超级管理员*/
        if (collect.contains("admin")) {
            List<Menu> allMenusToTree = menuService.list();
            return allMenusToTree;
        }
        List<Long> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
        /*根据角色获取菜单信息*/
        List<RoleMenu> roleMenus = getRoleMenuFromRoles(roleIds);//查询关联表找到对应的菜单权限ID
        List<Long> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        List<Menu> menus = menuService.listByIds(menuIds);
        /*这里就不需要处理为树结构了*/
        return menus;
    }


    @Override
    public List<Menu> getRouterInfoFromRole(List<Long> roleIds) {
        List<Role> roles = roleService.listByIds(roleIds);
        List<Menu> menus = null;
        /*判断是否是管理员*/
        boolean isAdmin = roles.stream().map(Role::getRoleKey).collect(Collectors.toList()).contains("admin");
        if (isAdmin) {
            menus = menuService.list();//查出全部权限信息
        } else {
            /*不是管理员，根据角色id查询出对应的权限*/
            QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
            wrapper.in("role_id", roleIds);
            List<RoleMenu> roleMenus = list(wrapper);
            List<Long> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            /*查询权限信息*/
            menus = menuService.listByIds(menuIds);
            /*筛选出路由信息*/
        }
        List<Menu> routers = menus.stream().filter(item -> item.getNodeType() == 2).collect(Collectors.toList());
        return routers;
    }

    @Override
    public List<Menu> getMenusFromRoleIds(List<Long> roleIds) {
        boolean isAdmin = roleService.isAdmin(roleIds);
        if (isAdmin) {
            List<Menu> list = menuService.list();
            return list;
        }
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.in("role_id", roleIds);
        List<RoleMenu> list = list(wrapper);
        List<Long> collect = list.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        return menuService.listByIds(collect);
    }

    @Override
    public UserPermissionVo getPermissionByUserId(long userId) {
        UserPermissionVo userPermissionVo = new UserPermissionVo();
//查询用户的角色集合
        List<Long> roleIds = userRoleService.getUserRoleIds(userId);
        List<Menu> allMenusToTree = null;
        //查询权限
        if (roleService.isAdmin(roleIds)) {
//            如果是超级管理员，那么就返回所有权限

            allMenusToTree = menuService.list();
        } else {
            allMenusToTree = getMenusFromRoleIds(roleIds);
        }
        List<Menu> menuTree = menuService.getMenuTree(allMenusToTree);
        userPermissionVo.setMenus(menuTree);
//        设置权限码
        userPermissionVo.setPermissionsCode(getMenuCodeByRoleIds(roleIds));
//        设置路由
        userPermissionVo.setRouters(getRouterInfoFromRole(roleIds));
        return userPermissionVo;
    }

    @Override
    public List<String> getMenuCodeByRoleIds(List<Long> roleIds) {
        List<Menu> menusFromRoleIds = getMenusFromRoleIds(roleIds);
        return menusFromRoleIds.stream().map(Menu::getMenuCode).collect(Collectors.toList());
    }

    @Override
    public List<Menu> getPermissionInfoByUserId(Long userId) {
        List<Long> roleIds = userRoleService.getUserRoleIds(userId);
        //查询权限
        if (roleIds.size() == 0) {
            log.error("用户权限为空");
            return new ArrayList<>();
        }
        if (roleService.isAdmin(roleIds)) {
//            如果是超级管理员，那么就返回所有权限
            return menuService.list();
        } else {
            return getMenusFromRoleIds(roleIds);
        }
    }

    @Override
    public List<String> getPermissionCodeByUserId(Long userId) {
        List<Menu> permissionInfoByUserId = getPermissionInfoByUserId(userId);
        return permissionInfoByUserId.stream().map(Menu::getMenuCode).collect(Collectors.toList());
    }

    @Override
    public void modifyRole(ModifyRoleVO modifyRoleVO) {
//修改角色数据
        roleService.updateById(modifyRoleVO.getRole());
//        修改角色具有的权限
        List<Long> havePermissionIds = modifyRoleVO.getHavePermissionIds();
//  删除该角色具有的所有权限，然后再插入
        LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenu::getRoleId, modifyRoleVO.getRole().getId());
        remove(wrapper);
//        判断为null或者数据为空，则说明该角色没有任何权限
        if (havePermissionIds == null || havePermissionIds.size() == 0) {
            return;
        }
        for (Long havePermissionId : havePermissionIds) {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenuId(havePermissionId);
            roleMenu.setRoleId(modifyRoleVO.getRole().getId());
            save(roleMenu);
        }
    }


    @Override
    public ModifyRoleVO getModifyRoleVO(String roleId) {
        ModifyRoleVO modifyRoleVO = new ModifyRoleVO();
//        获取角色数据
        Role byId = roleService.getById(roleId);
        modifyRoleVO.setRole(byId);
//        获取该角色的权限，和全部数据
        modifyRoleVO.setAllPermission(menuService.getAllMenusToTree());
        List<Menu> menuFromRoleId = getMenuFromRoleId(Long.valueOf(roleId));
        List<Long> collect = null;
        if (menuFromRoleId != null) {
            collect = menuFromRoleId.stream().map(Menu::getId).collect(Collectors.toList());
        }
        modifyRoleVO.setHavePermissionIds(collect);
        return modifyRoleVO;
    }
}
